package com.ruoyi.system.controller;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

import com.ruoyi.common.utils.MinioUtil;
import com.ruoyi.system.domain.MergeRequest;
import com.ruoyi.system.service.MinioService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.MineVideo;
import com.ruoyi.system.service.IMineVideoService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;

/**
 * 视频Controller
 * 
 * @author ruoyi
 * @date 2025-01-14
 */
@RestController
@RequestMapping("/system/video")
public class MineVideoController extends BaseController
{
    @Autowired
    private IMineVideoService mineVideoService;

    @Autowired
    private MinioUtil minioUtil;

    private static final Logger log = LoggerFactory.getLogger(MinioUtil.class);

    /**
     * 查询视频列表
     */
    @PreAuthorize("@ss.hasPermi('system:video:list')")
    @GetMapping("/list")
    public TableDataInfo list(MineVideo mineVideo)
    {
        startPage();
        List<MineVideo> list = mineVideoService.selectMineVideoList(mineVideo);
        return getDataTable(list);
    }

    /**
     * 导出视频列表
     */
    @PreAuthorize("@ss.hasPermi('system:video:export')")
    @Log(title = "视频", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, MineVideo mineVideo)
    {
        List<MineVideo> list = mineVideoService.selectMineVideoList(mineVideo);
        ExcelUtil<MineVideo> util = new ExcelUtil<MineVideo>(MineVideo.class);
        util.exportExcel(response, list, "视频数据");
    }

    /**
     * 获取视频详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:video:query')")
    @GetMapping(value = "/{videoId}")
    public AjaxResult getInfo(@PathVariable("videoId") Long videoId)
    {
        return success(mineVideoService.selectMineVideoByVideoId(videoId));
    }

    /**
     * 根据 training_id 查询视频列表
     */
    @PreAuthorize("@ss.hasPermi('system:video:list')")
    @GetMapping("/listByTrainingId/{trainingId}")
    public TableDataInfo listByTrainingId(@PathVariable("trainingId") Long trainingId)
    {
        startPage();
        List<MineVideo> list = mineVideoService.selectMineVideoListByTrainingId(trainingId);
        return getDataTable(list);
    }

    /**
     * 新增视频
     */
    @PreAuthorize("@ss.hasPermi('system:video:add')")
    @Log(title = "视频", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody MineVideo mineVideo)
    {
        mineVideo.setUploadedAt(new Date());
        return toAjax(mineVideoService.insertMineVideo(mineVideo));
    }

    /**
     * 修改视频
     */
    @PreAuthorize("@ss.hasPermi('system:video:edit')")
    @Log(title = "视频", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody MineVideo mineVideo)
    {
        mineVideo.setUpdatedAt(new Date());
        return toAjax(mineVideoService.updateMineVideo(mineVideo));
    }

    /**
     * 删除视频
     */
    @PreAuthorize("@ss.hasPermi('system:video:remove')")
    @Log(title = "视频", businessType = BusinessType.DELETE)
	@DeleteMapping("/{videoIds}")
    public AjaxResult remove(@PathVariable Long[] videoIds) {
        try {
            return toAjax(mineVideoService.deleteMineVideoByVideoIds(videoIds));
        } catch (RuntimeException e) {
            return AjaxResult.error(e.getMessage());
        }
    }


    /**
     * 上传培训视频
     */
    @PreAuthorize("@ss.hasPermi('system:video:add')")
    @Log(title = "培训视频上传", businessType = BusinessType.INSERT)
    @PostMapping("/upload/{trainingId}/{videoId}")
    public AjaxResult uploadTrainingVideo(
            @PathVariable Long trainingId,
            @PathVariable Long videoId,
            @RequestParam("file") MultipartFile file) {
        try {
            String videoUrl = minioUtil.uploadTrainingVideo(file, trainingId, videoId);
            return AjaxResult.success().put("url", videoUrl);
        } catch (Exception e) {
            log.error("视频上传失败", e);
            return AjaxResult.error("上传失败: " + e.getMessage());
        }
    }

    /**
     * 获取上传分片
     */

    @PreAuthorize("@ss.hasPermi('system:video:add')")
    @Log(title = "培训视频分片上传", businessType = BusinessType.INSERT)
    @GetMapping("/uploadedChunks")
    public AjaxResult getUploadedChunks(
            @RequestParam Long trainingId,
            @RequestParam Long videoId,
            @RequestParam String fileMd5) {

        String prefix = String.format("training-%d/video-%d/chunks/%s/",
                trainingId, videoId, fileMd5);

        List<String> chunks = minioUtil.listChunkObjects(
                minioUtil.getVideoBucketName(), prefix);

        List<Integer> uploaded = chunks.stream()
                .map(path -> Integer.parseInt(path.substring(path.lastIndexOf("/") + 1)))
                .collect(Collectors.toList());

        return AjaxResult.success().put("uploadedChunks", uploaded);
    }

    @PreAuthorize("@ss.hasPermi('system:video:add')")
    @Log(title = "培训视频分片上传", businessType = BusinessType.INSERT)
    @PostMapping("/uploadChunk/{trainingId}/{videoId}")
    public AjaxResult uploadChunk(
            @PathVariable Long trainingId,
            @PathVariable Long videoId,
            @RequestParam("file") MultipartFile file,
            @RequestParam String fileMd5,
            @RequestParam Integer chunkIndex) {

        try {
            String chunkPath = String.format("training-%d/video-%d/chunks/%s/%d",
                    trainingId, videoId, fileMd5, chunkIndex);

            minioUtil.uploadChunk(file, minioUtil.getVideoBucketName(), chunkPath);
            return AjaxResult.success();
        } catch (Exception e) {
            return AjaxResult.error("分片上传失败: " + e.getMessage());
        }
    }

    @PreAuthorize("@ss.hasPermi('system:video:add')")
    @Log(title = "培训视频分片上传", businessType = BusinessType.INSERT)
    @PostMapping("/mergeChunks/{trainingId}/{videoId}")
    public AjaxResult mergeChunks(
            @PathVariable Long trainingId,
            @PathVariable Long videoId,
            @RequestBody MergeRequest request) {

        try {
            String bucket = minioUtil.getVideoBucketName();
            String prefix = String.format("training-%d/video-%d/chunks/%s/",
                    trainingId, videoId, request.getFileMd5());
            String targetObject = String.format("training-%d/video-%d/%s",
                    trainingId, videoId, request.getFileName());

            String videoUrl = minioUtil.mergeChunks(bucket, prefix, targetObject);
            return AjaxResult.success().put("url", videoUrl);
        } catch (Exception e) {
            return AjaxResult.error("合并失败: " + e.getMessage());
        }
    }

}
